Skip to content

Issue #29: targeted task reconciliation - #50

Merged
myobie merged 39 commits into
mainfrom
agent/issue-29-targeted-reconcile
Jul 30, 2026
Merged

Issue #29: targeted task reconciliation#50
myobie merged 39 commits into
mainfrom
agent/issue-29-targeted-reconcile

Conversation

@myobie

@myobie myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Problem

Task-scoped reconciliation must avoid whole-catalog mutation and preserve sibling isolation. The motivating failure in #29 was a targeted agent/task change blocked by an unrelated slow workspace because materialization walked the entire host catalog.

What changed

  • Added exact local task resolution for runtime ids and qualified <host>.<agent>.<task> selectors.
  • Added selected reconcile planning for missing, live, dead, kept, retired, and unrunnable tasks.
  • Added st2 up --materialize-only --task <selector> for owner-only rendering.
  • Added st2 up --once --task <selector> for bounded owner-only materialization plus selected task reconciliation.
  • Kept single-file specs and unbounded targeted supervision fail-closed.
  • Preserved selected Codex lifecycle-hook gates, including direct-argv Codex launches, and made targeted CLI report errors nonzero.
  • Documented the R19 targeted reconciliation contract and operator command.

Safety contract

Unknown, ambiguous, and wrong-host selectors refuse before workspace writes or runner inspection. Materialization, hook gates, planning, and actions are restricted to the selected owner/task. Unrelated diagnostics remain visible, while sibling workspace content and live PTY PID/creation generation remain unchanged.

Proof

  • Pure selector and reconcile refusal/action matrices.
  • Two-agent KDL + recording-runner missing/live/dead matrix.
  • Owner render-failure and unrelated malformed-sibling diagnostic proofs.
  • CLI proof that refusal/render failure precedes pty list and that only the selected exec is started.
  • Hermetic real-PTY lifecycle proof preserving the sibling PID and createdAt generation across selected launch, adoption, and replacement.
  • Bounded ETXTBSY handling in the nomad replacement fixture so parallel binary-replacement gates are reliable.
  • Refreshed head 138acbc6e93cf91e5d0f320ab639eee5df041399 is a normal two-parent merge of accepted PR head 348f81546ea989c31a2f5ce396add82d53187bc9 and live main 6cec77485213a47893d7c1804d1942a42d4df4bf. The only manual conflict resolution preserves main's macOS-gated std::process::Command import.

Validation on refreshed head

  • Focused: cargo test --test targeted_reconcile --test reconcile --test run --test materialize --test nomad_survival --test exec_backend -- --test-threads=1
  • Full: cargo test --workspace --all-targets -- --test-threads=1
  • Focused and full Clippy with -D warnings
  • cargo doc --workspace --no-deps and cargo test --doc --workspace
  • PR-local rustfmt --edition 2024 --check
  • git diff --check
  • Hosted nix flake check --print-build-logs: run 30541681147 / job 90867702311

No live rollout.

Closes #29

myobie added 30 commits July 29, 2026 09:56
@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Live acceptance — R4 dual-final GREEN

Accepted exact head: 348f81546ea989c31a2f5ce396add82d53187bc9.

Fresh isolated release binary:

  • version: st2 0.1.0 — running from local source (348f815, 2 hours ago)
  • SHA-256: 29d1311e8feb821da3c5b98901bdb5ace6157a2f4ba4141f4c4f5f32e027281f

Exact commands, where $R4_ROOT is the fresh evidence directory:

"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/active/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/active/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/retired/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
"$R4_ROOT/cargo-target/release/st2" up --catalog "$R4_ROOT/fixtures/retired/catalog" --host hetz --once --task hetz.st2-pr50-acceptance-r4.selected
st2 doctor --catalog "$CATALOG" --host hetz --require-supervisor

Exact action receipts:

reconcile pass on host 'hetz':
  launched (1): hetz.st2-pr50-acceptance-r4.selected

reconcile pass on host 'hetz':
  adopted (1): st2-pr50-acceptance-r4

reconcile pass on host 'hetz':
  torn down (1): hetz.st2-pr50-acceptance-r4.selected

reconcile pass on host 'hetz':
  gc (1): hetz.st2-pr50-acceptance-r4.selected

All action commands exited 0 with empty stderr.

Process identity:

  • PID 115615
  • createdAt 2026-07-29T13:37:15.851Z
  • wrapper sh -c exec /usr/bin/sleep 3600
  • kernel start ticks 181454103, CLK_TCK=100
  • direct-floor remaining lifetime: AT1 3583; AT2 pre/post 3459
  • AT3 exited tuple preserved the generation and wrapper with exitCode=129

Isolation and final-state proof:

  • ACTIVE and RETIRED shadow catalogs strict-validated with 2 agents, 0 warnings, 0 errors.
  • AT1 rendered only the selected owner marker; same-owner sibling and unrelated owner/task remained absent.
  • AT2 retained the exact PID, creation generation, wrapper, start ticks, and HZ.
  • AT3 tore down only the selected task.
  • AT4 GC removed only the selected record.
  • AT5 production doctor passed with exit 0 and empty stderr.
  • Final R4 IDs were absent across PTY JSON/files, Hetz exec state, systemd, process command lines, and production catalog paths.
  • Final terminal set was empty.
  • Final PTY/process/exec/scope/catalog/render/lock/service/unit/installed-binary/freeze state was exact T0.
  • Production service remained MainPID=4149392, InvocationID=057336e2e1ec4e84aa903153bb17ef24.
  • Silber.root health-wake remained absent and the frozen declaration/template/render inputs remained unchanged.

Evidence receipts:

  • owner T0 aggregate: 8484e355b58196eadfdcff7dbaa8051eb0f8b66e0e8e1996bb47d3a802cb516f
  • owner 274-file final evidence-manifest SHA-256: b81df194d33c06f2d48c55b83e1ca9bc10fbeb6a92752492e5b082be85980281
  • owner sha256sum -c verification: pass
  • independent root verification: the same 274-file manifest verified; doctor stdout SHA-256 d284028415d747b92fd25c8f11255152217f1ae81bbeff1660260300436377de
  • independent final PTY SHA-256: 8f962cd8fc5d356230b3d5ed37bec7a66059cdcc295090967b8113318b9c7aad
  • independent final service SHA-256: 0ee76c541a1af0b64bdf153ecf230111922d224de040babf6ab4978452dee196
  • independent final freeze SHA-256: 5c8fc463b92d2f3cf8dd8a4fe5261e331157da3b09f79d8a883345d069120240

Owner and independent root dual-final receipts are GREEN. The worktree is clean and GitHub still reports this exact head mergeable/clean with Nix successful.

Nathan delegated final merge authority to the requested reviewer, schickling-codex, if approval, checks, and head remain green. The PR owner will not self-merge.

@myobie
myobie marked this pull request as ready for review July 29, 2026 13:49
@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Post-acceptance reviewer request blocker: GitHub returned Could not resolve user with login 'schickling-codex' for the exact delegated reviewer. The PR is ready and the R4 evidence receipt is published. No substitute reviewer was requested, and the owner will not self-merge.

@myobie

myobie commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Correction to the reviewer blocker above: the intended reviewer login is schickling-assistant; schickling-codex was a CoS transcription error. GitHub exposes schickling-assistant with write permission on this repository. Nathan delegates final merge authority to that reviewer if approval, checks, and the accepted head remain green. The PR owner will not self-merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

targeted materialize/reconcile selector needed for shortest-path agent changes

1 participant